package com.zu.commu.remote.process;

import com.zu.commu.context.Config;
import com.zu.commu.exception.CommuException;
import com.zu.commu.interf.Action;
import com.zu.commu.interf.Command;
import com.zu.commu.interf.Data;
import com.zu.commu.interf.Order;
import com.zu.commu.interf.meter.Driver;
import com.zu.commu.interf.meter.Request;
import com.zu.commu.local.process.LocalMeterProcess;
import com.zu.commu.remote.session.Session;
import com.zu.commu.saveData.DataQueue;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

public class MeterProcess
{
  private static Logger log = Logger.getLogger("com.automic.commu.remote.process.MeterProcess");
  private Session se;

  public MeterProcess(Session se)
  {
    this.se = se;
  }

  public void processData(int threadNum, byte[] bs)
  {
    String gprsId = (String)this.se.getAttribute("gprsId");
    Request request = getRequest(gprsId);
    if (request == null) {
      return;
    }
    analyseData(request, bs, gprsId);
  }

  private Request getRequest(String gprsId)
  {
    Config cf = Config.instance();
    String protocol = cf.getMeterProcotolOfGPRSID(gprsId);
    if (protocol == null)
    {
      log.error("没有得到号码为" + gprsId + "的GPRS的通信协议。可能配置的sim卡号与实际的不相附合。");
      return null;
    }
    Driver driver = cf.getDriverOfMeterProtocol(protocol);
    return driver.getRequest();
  }

  public void analyseData(Request request, byte[] s, String gprsId)
  {
    Action action = request.analyseData(s);

    if (action.equals(Action.SENDCENTER))
    {
      Data[] data = request.getCenterData();
      Order order = request.dataFromwhatOrder();
      if ((data != null) && (data.length > 0))
        sendCenter(data, order);
    }
    else if (action.equals(Action.SENDREMOTE))
    {
      byte[] buf = request.getRemoteData();

      sendRemote(buf, gprsId, new Command(), Order.NOTORDER);
    } else if (action.equals(Action.SENDREMOTEANDCENTER))
    {
      byte[] buf = request.getRemoteData();

      sendRemote(buf, gprsId, new Command(), Order.NOTORDER);

      Data[] data = request.getCenterData();
      Order order = request.dataFromwhatOrder();
      if ((data != null) && (data.length > 0))
        sendCenter(data, order);
    }
    else if (action.equals(Action.NOACTION))
    {
      log.info("没有动作。");
    } else if (action.equals(Action.ERROR))
    {
      log.error(request.getError());
    }
  }

  private void sendRemote(byte[] buf, String gprsId, Command com, Order order)
  {
    if (buf == null) {
      log.error("出错！向远端模块发送的数据为空。");
    }

    try
    {
      LocalMeterProcess lmp = new LocalMeterProcess();
      lmp.sendRemoteDirect(gprsId, order, com, buf);

      if (Level.INFO.isGreaterOrEqual(log.getEffectiveLevel()))
        try {
          String hex = byte2Hex(buf);
          log.info("向远端发送命令：" + hex);
        } catch (Exception e) {
          e.printStackTrace();
        }
    }
    catch (Exception e) {
      log.error("向远端发送数据出错 。", e);
    }
  }

  private void sendCenter(Data[] data, Order order)
  {
    String[] commandIds = this.se.putOutCommandId(order);
    Data temp = null;

    if (commandIds == null)
    {
      for (int i = 0; i < data.length; i++) {
        data[i].setGprsId((String)this.se.getAttribute("gprsId"));
        DataQueue dq = DataQueue.instance();
        if ((order.equals(Order.CALL)) || 
          (order.equals(Order.COMMON)) || 
          (order.equals(Order.AUTOREPROT_2_0))) {
          dq.setDataToSecondQueue(data[i]);
        }
        else {
          log.error("数据是命令结果，但找不到这个命令的ID（可能是等待超时，命令ID被清除），丢弃此结果数据！");
        }
      }
    }
    else
      for (int j = 0; j < commandIds.length; j++)
        for (int i = 0; i < data.length; i++) {
          temp = data[i];
          temp.setGprsId((String)this.se.getAttribute("gprsId"));
          temp.setCommandId(commandIds[j]);
          DataQueue dq = DataQueue.instance();

          dq.setDataToFirstQueue(temp);
        }
  }

  private String byte2Hex(byte[] b)
    throws CommuException
  {
    String rString = "";
    String temp = "";
    try {
      for (int i = 0; i < b.length; i++) {
        int c = b[i];
        temp = Integer.toHexString(c & 0xFF);
        if (temp.length() == 1) {
          temp = "0" + temp;
        }
        rString = rString + temp;
      }
    } catch (Exception e) {
      throw new CommuException().setMessage("字节数组转换成十六进制的字符串出错！", null);
    }
    return rString;
  }
}